<!doctype html>
<html lang="zh-CN"><head><script src="/livereload.js?mindelay=10&amp;v=2&amp;port=1313&amp;path=livereload" data-no-instant defer></script>
    <title>薛尧的博客</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="" />

    
    
    
    <link rel="stylesheet" href="../../../css/theme.min.css">

    
    
    
    
    <link rel="stylesheet" href="../../../css/custom.min.css">
    

    
</head>
<body>
        <div id="content" class="mx-auto"><header class="container mt-sm-5 mt-4 mb-4 mt-xs-1">
    <div class="row">
        
        <div class="col-sm-4 col-12 text-sm-right text-center pt-sm-4">
            <a href="../../../" class="text-decoration-none">
                <img id="home-image" class="rounded-circle"
                    
                        src="https://ueyao.github.io/image-hosting/blog/avatar.png"
                    
                />
            </a>
        </div>
        <div class="col-sm-8 col-12 text-sm-left text-center">
        
            <h2 class="m-0 mb-2 mt-4">
                <a href="../../../" class="text-decoration-none">
                    
                        薛尧
                    
                </a>
            </h2>
            <p class="text-muted mb-1">
                
                    Java Developer | Short Video Creator
                
            </p>
            <ul id="nav-links" class="list-inline mb-2">
                
                
                    <li class="list-inline-item">
                        <a class="badge badge-white " href="../../../about/" title="关于">关于</a>
                    </li>
                
                    <li class="list-inline-item">
                        <a class="badge badge-white " href="../../../post/" title="文章">文章</a>
                    </li>
                
                    <li class="list-inline-item">
                        <a class="badge badge-white " href="../../../categories/" title="分类">分类</a>
                    </li>
                
            </ul>
            <ul id="nav-social" class="list-inline">
                
                    <li class="list-inline-item mr-3">
                        <a href="http://github.com/flowstone" target="_blank">
                            <i class="fab fa-github fa-1x text-muted"></i>
                        </a>
                    </li>
                
                    <li class="list-inline-item mr-3">
                        <a href="mailto:xueyao.me#gmail.com" target="_blank">
                            <i class="fas fa-at fa-1x text-muted"></i>
                        </a>
                    </li>
                
            </ul>
        </div>
    </div>
    <hr />
</header>
<div class="container">
    <div class="pl-sm-2">
        <div class="mb-3">
            <h3 class="mb-0">Docker入门-介绍和安装</h3>
            
            <small class="text-muted">发布于 2019-08-14</small>
        </div>

        <article>
            <h2 id="docker容器">Docker容器</h2>
<h3 id="docker是什么">Docker是什么</h3>
<p>Docker最初是dotCloud公司创建人Solomon Hykes在法国期间发起的一个公司内部项目，它是基于dotCloud公司多年云服务技术的一次革新，并于2013年3月以Apache2.0授权协议开源，主要项目代码在Github上进行维护。Docker项目后来加入了Linux基金会，并成立推动开放容器联盟(OCI).</p>
<p>Docker使用Google公司推出的Go语言进行开发实现，基于Linux内核的cgroup,namespace,以及AUFS类的Union FS等技术，对进程进行封装隔离，属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程，因此也称为容器。</p>
<p>Docker在容器的基础上，进行了进一步的封装，从文件系统、网络互联至进程隔离等待，极大的简化了容器的创建和维护。使得Docker技术比虚拟机技术更为轻便、快捷。</p>
<h3 id="docker和传统虚拟机">Docker和传统虚拟机</h3>
<p><img src="https://ueyao.github.io/image-hosting/blog/2019/docker-vm.png" alt="docker和传统虚拟机比较"></p>
<p>传统虚拟机技术是虚拟出一套硬件后，在其上运行一个完整操作系统，在该系统上再运行所需应用进程；</p>
<p>而容器内的应用进程直接运行于宿主的内核，容器内没有自己的内核，而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。</p>
<h3 id="为什么要使用docker">为什么要使用Docker</h3>
<h4 id="docker优势">Docker优势</h4>
<ul>
<li>更高效的利用系统资源</li>
<li>更快速的启动时间</li>
<li>一致的运行环境</li>
<li>持续交付和部署</li>
<li>更轻松的迁移</li>
<li>更轻松的维护和扩展</li>
</ul>
<h4 id="对比传统虚拟机总结">对比传统虚拟机总结</h4>
<table>
  <thead>
      <tr>
          <th>特性</th>
          <th>容器</th>
          <th>虚拟机</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>启动</td>
          <td>秒级</td>
          <td>分钟级</td>
      </tr>
      <tr>
          <td>硬盘使用</td>
          <td>一般为MB</td>
          <td>一般为GB</td>
      </tr>
      <tr>
          <td>性能</td>
          <td>接近原生</td>
          <td>较弱</td>
      </tr>
      <tr>
          <td>系统支持量</td>
          <td>单机支持上千个容器</td>
          <td>一般几十个</td>
      </tr>
  </tbody>
</table>
<h3 id="docker架构">Docker架构</h3>
<p><img src="https://ueyao.github.io/image-hosting/blog/2019/docker-framework.png" alt=""></p>
<p>Docker使用客户端-服务器(C/S)架构模式，使用远程API来管理和创建Docker容器。</p>
<h3 id="docker基本概念">Docker基本概念</h3>
<h4 id="docker镜像">Docker镜像</h4>
<p>我们都知道，操作系统分为内核和用户空间。对于Linux而言，内核启动后，会挂载root文件系统为其提供用户空间支持。而Docker镜像(Image),就相当于是一个root文件系统。比如官方镜像centos:7.6就包含了完整的一套centos7.6最小系统的root文件系统。</p>
<p>Docker镜像是一个特殊的文件系统，除了提供容器运行时所需的程序、库、资源、配置等文件外，还包含了一些为运行时准备的一些配置参数(如匿名半卷、环境变量、用户等)。镜像不包含任何动态数据，其内容在构建之后也不会被改变。</p>
<h4 id="docker镜像分层存储">Docker镜像分层存储</h4>
<p>因为镜像包含操作系统完整的root文件系统，其体积往往是庞大的，因此在Docker设计时将其设计为分层存储的架构。镜像只是一个虚拟的概念，其实际体现并非由一个文件组成，而是由一组文件系统组成，或者说，由多层文件系统联合组成。</p>
<p>镜像构建时，会一层层构建，前一层是后一层的基础。每一层构建完就不会再发生改变，后一层上的任何改变只发生在自己这一层。在构建镜像的时候，需要额外小心，每一层尽量只包含该层需要添加的东西，任何额外的东西应该在该层构建结束前清理掉。</p>
<p>分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层，然后进一步添加新的层，以定制自己所需的内容，构建新的镜像。</p>
<h4 id="docker容器-1">Docker容器</h4>
<p>镜像(Image)和容器(Container)的关系，就像Java中的类和实例一样，镜像是静态的定义，容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。</p>
<p>前面讲过镜像使用的是分层存储，容器也是如此。每一个容器运行时，是以镜像基础层，在其上创建一个当前容器的存储层，我们可以称这个为容器运行时读写而准备的存储层为容器存储层。</p>
<p>容器存储层的生存周期和容器一样，容器消亡时，容器存储层也随之消亡。因此，任何保存于容器存储层的信息都会随容器删除而丢失。</p>
<p>按照Docker最佳实践的要求，容器不应该向其存储内写入任何数据，容器存储层要保持无状态化。所有的文件写入操作，都应该使用Volume数据卷、或者绑定宿主目录，在这些位置的读写会跳过容器存储层，直接对宿主(或网络存储)发生读写，其性能和稳定性更高。</p>
<p>数据卷的生存周期独立于容器，容器消亡，数据卷不会消亡。因此，使用数据卷后，容器删除或者重新运行之后，数据却不会丢失。</p>
<h4 id="docker仓库">Docker仓库</h4>
<p>镜像构建完成后，可以很容易的在当前宿主机上运行，但是，如果需要在其它服务器上使用这个镜像，我们就需要一个集中的存储、分发镜像的服务，Docker Registry就是这样的服务。</p>
<p>一个Docker Registry中可以包含多个仓库(Repository)；每个仓库可以包含多个标签(Tag)；每个标签对应一个镜像。</p>
<p>通常，一个仓库会包含同一个软件不同版本的镜像，而标签就常用于对应软件的各个版本。我们可以通过&lt;仓库名&gt;:&lt;标签&gt;的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签，将以latest作为默认标签。</p>
<p>以centos镜像为例，centos是仓库的名字，其内包含有不同的版本标签，如，6.9，7.5。我们可以通过centos:6.9，或者centos:7.5来具体指定所需哪个版本的镜像。如果忽略了标签，比如centos,那将视为centos:latest。</p>
<p>仓库名经常以两段式路径形式出现，比如study/nginx，前者往往意味着Docker Registry多用户环境下的用户名，后者则往往是对应的软件名。但这并非绝对，取决于所使用的具体Docker Registry的软件或服务。</p>
<h5 id="docker-registry公开仓库">Docker Registry公开仓库</h5>
<p>常用的Registry是官方的Docker Hub，这也是默认的Registry。除此以外，还有CoreOS的Quay.io，CoreOS相关的镜像存储在这里；Google的Google Container Registry,Kubernetes的镜像使用的就是这个服务。</p>
<p>国内的一些云服务商提供了针对Docker Hub的镜像服务。这些镜像服务被称为加速器。常见的有阿里加速器、DaoCloud加速器等。使用加速器会直接从国内的地址下载Docker Hub的镜像，比直接从Docker Hub下载速度会提高很多。</p>
<p>国内也有一些云服务商推荐类型于Docker Hub的公开服务。如网易云镜像服务、
DaoCloud镜像市场、阿里云镜像库等。</p>
<h2 id="安装">安装</h2>
<h3 id="docker版本命名">Docker版本命名</h3>
<p>Docker在1.13版本之后，从2017年的3月1日开始，版本命名规则变为如</p>
<table>
  <thead>
      <tr>
          <th>项目</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>版本格式</td>
          <td>YY.MM</td>
      </tr>
      <tr>
          <td>Stable版本</td>
          <td>每个季度发行</td>
      </tr>
      <tr>
          <td>Edge版本</td>
          <td>每个月发行</td>
      </tr>
      <tr>
          <td>当前Docker CE Stable版本</td>
          <td>18.09</td>
      </tr>
      <tr>
          <td>当前Docker CE Edge版本</td>
          <td>18.09</td>
      </tr>
  </tbody>
</table>
<p>同时Docker划分为CE和EE。CE即社区版(免费，支持周期三个月)强调安全，付费使用。</p>
<h3 id="centos安装docker">CentOS安装Docker</h3>
<p>1、系统要求</p>
<p>Docker CE支持64位版本CentOS7,并且要求内核版本不低于3.10。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># 查看当前系统内核</span>
</span></span><span style="display:flex;"><span>uname -r
</span></span></code></pre></div><p>2、卸载旧版本</p>
<p>旧版本的Docker称为docker或者docker-engine,使用以下命令卸载旧版本：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo yum remove docker docker-common docker-selinux docker-engine
</span></span></code></pre></div><p>3、使用yum安装</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo yum install docker-ce
</span></span></code></pre></div><p>4、使用脚本安装</p>
<p>在测试或开发环境中Docker官方为了简化安装流程,提供了一套便捷的安装脚本，系统上可以使用这套脚本安装：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -fsSL https://get.docker.com -o get-docker.sh
</span></span><span style="display:flex;"><span>sudo sh get-docker.sh --mirror Aliyun
</span></span></code></pre></div><p>执行这个命令后，脚本就会自动的将一切做准备工作做好，并且把Docker CE的Edge装在系统中。</p>
<p>5、启动Docker CE</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo systemctl enable docker <span style="color:#75715e">#设置开启启动</span>
</span></span><span style="display:flex;"><span>sudo systemctl start docker
</span></span></code></pre></div><p>6、建立docker用户组</p>
<p>默认情况下，docker命令会使用Unix socket与Docker引擎通讯。而只有root用户和docker组的用户才可以访问Docker引擎的Unix socket。一般Linux系统上不会直接使用root用户进行操作。因此，需要将使用docker的用户加入docker用户组。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo groupadd docker <span style="color:#75715e">#建立docker组</span>
</span></span><span style="display:flex;"><span>sudo usermod -aG docker <span style="color:#75715e">#USER #将当前用户加入docker组</span>
</span></span></code></pre></div><p>7、测试Docker是否安装正确</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker run hello-world <span style="color:#75715e">#启动一个基于hello-world镜像的容器</span>
</span></span></code></pre></div><p>若能正常输出以上信息，则说明安装成功。</p>
<h3 id="centos卸载docker">CentOS卸载Docker</h3>
<p>1、 删除docker安装包</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo yum remove docker-ce
</span></span></code></pre></div><p>2、删除docker镜像</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo rm -rf /var/lib/docker
</span></span></code></pre></div><h3 id="镜像加速器">镜像加速器</h3>
<p>国内从Docker Hub拉取镜像有时会遇到困难，此时可以配置镜像加速器。Docker官方和国内很多云服务商都提供了国内加速器服务，例如：</p>
<ul>
<li>Docker官方提供的中国registry mirror</li>
<li>阿里云加速器</li>
<li>DaoCloud加速器</li>
<li>163加速器</li>
</ul>
<p>接下来我们以163加速器为例进行介绍。</p>
<h4 id="centos7配置镜像加速">CentOS7配置镜像加速</h4>
<p>对于使用systemd的系统，请在/etc/docker/daemon.json中写入如下内容(如果文件不存在请新建该文件)</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;registry-mirrors&#34;</span>:[
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;http://hub-mirror.c.163.com&#34;</span>
</span></span><span style="display:flex;"><span>    ]
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>重新启动服务生效</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo systemctl daemon-reload
</span></span><span style="display:flex;"><span>sudo systemctl restart docker
</span></span></code></pre></div><p>查看当前docker信息</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker info
</span></span></code></pre></div><p><img src="https://ueyao.github.io/image-hosting/blog/2019/docker-163.png" alt="docker信息"></p>

        </article>
    </div>

    <div id="disqus_thread"></div>
<script>
    window.disqus_config = function () {
    
    
    
    };
    (function() {
        if (["localhost", "127.0.0.1"].indexOf(window.location.hostname) != -1) {
            document.getElementById('disqus_thread').innerHTML = 'Disqus comments not available by default when the website is previewed locally.';
            return;
        }
        var d = document, s = d.createElement('script'); s.async = true;
        s.src = '//' + "xie-yao-de-bo-ke" + '.disqus.com/embed.js';
        s.setAttribute('data-timestamp', +new Date());
        (d.head || d.body).appendChild(s);
    })();
</script>
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
<a href="https://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>

            </div>
        </div><footer class="text-center pb-1">
    <small class="text-muted">
        
        &copy; Copyright 2024
        
        |
        <a href="https://beian.miit.gov.cn/" target="_blank">苏ICP备14012079号</a>
        <br />
        由 <a href="https://gohugo.io/" target="_blank">Hugo</a> 强力驱动
        | 主题 <a href="https://github.com/austingebauer/devise" target="_blank">Devise</a>
        <br />

    </small>
</footer></body>
</html>
